home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-04-07 | 50.3 KB | 1,229 lines |
- _FRACTALS IN THE REAL WORLD_
- by Dick Oliver
-
- [LISTING 1]
-
- /****************************************************************
- SIERP.C -- (C) 1990 by Dick Oliver, R1 Box 5140, Morrisville, VT 05661
- A program to "draw" and "paint" Sierpinksi's Triangle, defined by a
- "seed" (or "parent") shape and three transformations of that shape
- ("children"). The author makes no claims as to readability or
- suitability for a particular task, but I'll be happy to give advice
- and assistance.
- *****************************************************************/
-
- #include <stdio.h> /* For getch() */
- #include <math.h> /* For cos() and sin() */
- #include <graph.h> /* For graphics calls */
-
- #include "sierp.h" /* You can change this for other template definitions */
-
- int seedx[NPOINTS] = {SEEDX}, /* The "parent" polygon */
- seedy[NPOINTS] = {SEEDY};
-
- /* The tranformations which define the "children" */
- float movex[NTRANS] = {MOVEX}, /* Displacement */
- movey[NTRANS] = {MOVEY},
- sizex[NTRANS] = {SIZEX}, /* Size change */
- sizey[NTRANS] = {SIZEY},
- spinx[NTRANS] = {SPINX}, /* Rotation */
- spiny[NTRANS] = {SPINY},
-
- /* The transformation matrix T, computed from the above variables */
- Ta[NTRANS], Tb[NTRANS], Tc[NTRANS], Td[NTRANS];
-
- /* Function prototypes */
- void draw(float a, float b, float c, float d, float mx, float my, int iter);
- void paint(int mx, int my);
-
- void main(void)
- { int t;
- _setvideomode(_VRES16COLOR); /* Initialize the screen */
- _clearscreen(_GCLEARSCREEN);
-
- /* Compute a,b,c,d from the move, size, and spin variables */
- for (t = 0; t < NTRANS; t++)
- { Ta[t] = sizex[t] * cos(spinx[t]);
- Tb[t] = - sizey[t] * sin(spiny[t]);
- Tc[t] = sizex[t] * sin(spinx[t]);
- Td[t] = sizey[t] * cos(spiny[t]);
- }
- /* Invoke draw with an initial transformation to move the triangle
- to the center of the screen, unchanged in size or rotation */
- draw(1.0, 0.0, 0.0, 1.0, (float) CENTERX, (float) CENTERY, NLEVELS);
- _settextposition(30,0);
- _outtext("Press any key to paint.");
- getch();
- _clearscreen(_GCLEARSCREEN);
-
- /* Invoke paint, specifying the center of the screen */
- paint(CENTERX, CENTERY);
- _settextposition(30,0);
- _outtext("Press any key to exit.");
- getch();
-
- _setvideomode(_DEFAULTMODE); /* Go back to text mode and exit */
- }
-
-
- /* This recursive routine draws one "parent" polygon, then calls itself
- to draw the "children" using the transformations defined above */
- void draw(float a, float b, float c, float d, float mx, float my, int iter)
- { int t;
- iter--; /* Count one more level of drawing depth */
- { /* Use a,b,c,d,mx,my to transform the polygon */
- float x1, y1; /* Point on the parent */
- int p, x2[NTRANS], y2[NTRANS]; /* Points on the child */
- for (p = 0; p < NPOINTS; p++)
- { x1 = seedx[p];
- y1 = seedy[p];
- x2[p] = a * x1 + b * y1 + mx;
- y2[p] = c * x1 + d * y1 + my;
- }
- /* Now draw the new polygon on the screen */
- _moveto(x2[NPOINTS - 1], y2[NPOINTS - 1]);
- for (p = 0; p < NPOINTS; p++) _lineto(x2[p], y2[p]);
- }
- if (iter < 0) return; /* If we're at the deepest level, back out */
-
- /* Do a recursive call for each "child" of the polygon we just drew */
- for (t = 0; t < NTRANS; t++)
- { draw(Ta[t] * a + Tc[t] * b,
- Tb[t] * a + Td[t] * b,
- Ta[t] * c + Tc[t] * d,
- Tb[t] * c + Td[t] * d,
- movex[t] * a + movey[t] * b + mx,
- movex[t] * c + movey[t] * d + my,
- iter);
- }
- }
-
-
- /* This routine uses "random iteration" to paint the fractal dot-by-dot.
- The resulting shape will be the same as if we called draw with a
- huge value for the number of levels */
- void paint(int mx, int my)
- { int t;
- unsigned long ct = 0; /* Counter for number of dots painted so far */
- float x1 = 0.0, y1 = 0.0, x2, y2; /* Current and next dot */
-
- /* Keep going until a key is pressed or we reach the COUNT limit */
- while(!kbhit() && (++ct < COUNT))
- { t = rand() % NTRANS; /* Pick one of the transformations at random */
-
- /* Then move from a dot on the "whole" to the corresponding dot
- on some transformed "part" */
- x2 = x1 * Ta[t] + y1 * Tb[t] + movex[t];
- y2 = x1 * Tc[t] + y1 * Td[t] + movey[t];
- x1 = x2, y1 = y2;
-
- /* Skip the first few dots--it takes a while to "find" the fractal */
- if (ct > 8) _setpixel((int) x2 + mx, (int) y2 + my);
- }
- }
-
-
- [LISTING TWO]
-
- /****************************************************************
- SIERP.H -- Header file for Sierpinski's Triangle template
- This (and the other header files like it) can be used to define
- the initial fractal template for the SIERP.C and FRACDRAW.C programs
- *****************************************************************/
-
- #define NPOINTS 3 /* Number of points on the "parent" polygon */
- #define NTRANS 3 /* Number of transformed "children" */
- #define NLEVELS 6 /* Number of levels to draw */
- #define COUNT 10000 /* Number of dots to paint */
- #define CENTERX 320 /* Center of the screen x, y*/
- #define CENTERY 240
- #define SEEDX -200, 200, 0 /* The "parent" polygon */
- #define SEEDY -200, -200, 200
-
- /* The tranformations which define the "children" */
- #define MOVEX -100.0, 100.0, 0.0 /* Displacement */
- #define MOVEY -100.0, -100.0, 100.0
- #define SIZEX 0.5, 0.5, 0.5 /* Size change */
- #define SIZEY 0.5, 0.5, 0.5
- #define SPINX 0.0, 0.0, 0.0 /* Rotation */
- #define SPINY 0.0, 0.0, 0.0
-
- /* The following color definitions are ignored by the SIERP program
- and used only by FRACDRAW.
- PALETTE defines the 16-color VGA palette
- COLOR intializes a two-dimensional array with color values:
- each column in the array definition below corresponds to one level
- of detail, and each row corresponds to a "part", or transformation.
- Note that the array only needs to be 6 by 3 for the template defined
- above, but more rows are included in case the user inserts additional
- "parts".
- */
-
- #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
- _BLUE, _MAGENTA, _BROWN, _WHITE, \
- _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
- _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
-
- #define COLOR {{2, 2, 2, 2, 2, 2},\
- {1, 1, 1, 1, 1, 1},\
- {5, 5, 5, 5, 5, 5},\
- {4, 4, 4, 4, 4, 4},\
- {2, 2, 2, 2, 2, 2},\
- {3, 3, 3, 3, 3, 3},\
- {7, 7, 7, 7, 7, 7},\
- {8, 8, 8, 8, 8, 8},\
- {1, 1, 1, 1, 1, 1}}
-
-
- [LISTING THREE]
-
- /*****************************************************************
- MAPLE.H --- Header file for maple tree template
- This (and the other header files like it) can be used to define
- the initial fractal template for the SIERP.C and FRACDRAW.C programs
- *****************************************************************/
- #define NPOINTS 4 /* Number of points on the "parent" polygon */
- #define NTRANS 3 /* Number of transformed "children" */
- #define NLEVELS 6 /* Number of levels to draw */
- #define COUNT 10000 /* Number of dots to paint */
- #define CENTERX 320 /* Center of the screen */
- #define CENTERY 350
- /* The "parent" polygon */
- #define SEEDX 6,20,-6,-12
- #define SEEDY -120,120,120,-120
- /* The tranformations which define the "children" */
- #define MOVEX -6.1,-46,48 /* Displacement */
- #define MOVEY -156,-40,-38
- #define SIZEX .65,.57,.58 /* Size change */
- #define SIZEY .56,.77,.82
- #define SPINX 6.28,5.52,.44 /* Rotation */
- #define SPINY 6.28,5.52,.44
-
- /* The following color definitions are ignored by the SIERP program
- and used only by FRACDRAW. See similar #defines in SIERP.H (Listing 2)
- */
- #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
- _BLUE, _MAGENTA, _BROWN, _WHITE, \
- _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
- _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
-
- #define COLOR {{6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2}}
-
- [LISTING FOUR]
-
- /*****************************************************************
- FRACDRAW.C -- Drawing with fractals
- Copyright 1990 by Dick Oliver, R1 Box 5140, Morrisville, VT 05661
- A program for interactive fractal drawing.
- The author makes no claims as to readability or suitability for a
- particular task, but I'll be happy to give advice and assistance.
- *****************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <graph.h>
- #include <math.h>
- #include <ctype.h>
- #include <bios.h>
-
- /* #include file for initial template definition, can be changed */
- #include "maple.h"
- /* Numerical constants */
- #define PI 3.141592
- #define TWOPI 6.283853
- #define HALFPI 1.570796
- #define ALMOSTZERO 0.00002
- #define MAXSIZE 0.998
- #define MAXINT 32767
- /* Keyboard constants */
- #define ENTER 13
- #define BACKSPACE 8
- #define ESC 27
- #define END -'O'
- #define HOME -'G'
- #define INSERT -'R'
- #define DELETE -'S'
- #define TAB 9
- #define UNTAB -15
- #define UP -'H'
- #define DN -'P'
- #define LT -'K'
- #define RT -'M'
- #define NULLKEY '^'
-
- /* Generic getch() replacement */
- #define geta if ((a = getch()) == 0) a = -getch();\
- else if (a > 0) a = toupper(a)
-
- /* Main menu */
- #define MENUMSG "ACTION KEY\n"\
- " Draw D\n"\
- " Paint P\n"\
- " Both B\n"\
- " Next Part Tab\n"\
- " NextPoint ~\n"\
- " Insert Ins\n"\
- " Delete Del\n"\
- " Grow *\n"\
- " Shrink /\n"\
- " Spin + -\n"\
- " Skew ; \'\n"\
- " Squish [\n"\
- " Stretch ]\n"\
- " Quit ESC\n\n\n"\
- " DRAWING\n WITH\n FRACTALS\n\n"\
- " (C) 1990 by\n Dick Oliver"
-
- #define MENUKEYS {'D', 'P', 'B', TAB, '`', INSERT, DELETE, \
- '*', '/', '+', ';', '[', ']', ESC}
- #define MENUWD 15 /* width of menu in characters */
- #define NMENUITEMS 14 /* number of menu items */
- #define HAND 64 /* size of handle in pixels */
- #define MAXPTS 19 /* max. no. of points on seed */
- #define MAXTRANS 19 /* max. no. of parts of template */
-
- /* template variables:
- spininc is the amount to rotate (in radians) each time spin is picked
- sizeinc is the amount to grow or shrink
- ra, rb, rc, rd, rmx, and rmy are the reverse of the initial tranformation
- fa, fb, fc, and fd are the tranformations computed from
- sizex, sizey, spinx, and spiny
- movex and movey are the translation part of the transformations
- asprat is the aspect ratio (always 1 for VGA)
- fx and fy are used for various temporary storage purposes
- x and y are the points on the seed polygon */
-
- float sizeinc = 0.16, spininc = PI / 16,
- ra, rb, rc, rd, rmx, rmy,
- fa[MAXTRANS + 1], fb[MAXTRANS + 1], fc[MAXTRANS + 1], fd[MAXTRANS + 1],
- sizex[MAXTRANS + 1] = {1, SIZEX}, sizey[MAXTRANS + 1] = {1, SIZEY},
- spinx[MAXTRANS + 1] = {0, SPINX}, spiny[MAXTRANS + 1] = {0, SPINY},
- movex[MAXTRANS + 1] = {CENTERX, MOVEX},
- movey[MAXTRANS + 1] = {CENTERY, MOVEY},
- asprat, fx, fy, x[MAXPTS] = {SEEDX}, y[MAXPTS] = {SEEDY};
-
- /* menu vars */
- char a, menukeys[] = MENUKEYS;
-
- /* xtop, etc. are the points on the handle
- drawclr is the text and handle color
- xx, yy, midx, and midy are used for various pixel-shuffling operations
- menuitem is the current menu choice
- hand is the size of the handle in pixels
- sk is used to keep track of when to re-sketch the template
- xo and yo are the current template corners for quick erasing
- thispt & thistran are the current point/part
- npts is the number of point, ntrans is the number of parts,
- level is the number of levels of detail to draw or paint
- color determines the color to make each part at each level
- */
- int xtop, ytop, xctr, yctr, xlft, ylft, xrgt, yrgt,
- drawclr, i, j, xx, yy, midx, midy, menuitem = 0, hand = HAND, sk,
- xo[MAXTRANS + 1][MAXPTS], yo[MAXTRANS + 1][MAXPTS], moveinc = 16,
- thispt = 0, thistran = 0, npts = NPOINTS, ntrans = NTRANS,
- level = NLEVELS - 1, color[MAXTRANS][NLEVELS] = COLOR;
-
- /* ptmode means we're in "point" mode rather than "part" mode*/
- enum {OFF, ON} ptmode = OFF;
-
- /* standard Microsoft video variables */
- struct videoconfig vc;
- long palette[16] = PALETTE;
-
- /* these function prototypes are needed to avoid confusion about parameter
- * types (most of the functions aren't prototyped) */
- void draw(float a, float b, float c, float d, float mx, float my, int iter);
- void warp(float spinxinc, float spinyinc, float sizexinc, float sizeyinc);
-
- main()
- { hello(); /* initialize everything */
- while(1) /* the main event-processing loop */
- { geta; /* geta is a #define */
- switch(a) /* what shall we do now? */
- { case BACKSPACE:
- case ' ':
- /* move ">" to new menu item */
- _settextposition(menuitem + 2, 1);
- _outtext(" ");
- if (a == ' ')
- { if (++menuitem == NMENUITEMS) menuitem = 0;
- }
- else if (--menuitem < 0) menuitem = NMENUITEMS - 1;
- _settextposition(menuitem + 2, 1);
- _outtext(">");
- break;
- case ENTER: /* pick a menu item */
- ungetch(menukeys[menuitem]);
- break;
- default:
- sk = 0;
- switch(a)
- { case LT: case DN:
- case RT: case UP:
- /* move a point or part of the template */
- xx = 0, yy = 0;
- switch (a)
- { case LT: xx = -moveinc; break;
- case RT: xx = moveinc; break;
- case UP: yy = -moveinc; break;
- case DN: yy = moveinc; break;
- }
- if (!ptmode && (thistran == 0))
- *movex += xx, *movey += yy;
- else
- { if (ptmode)
- { x[thispt] += xx * ra + yy * rb;
- y[thispt] += xx * rc + yy * rd;
- }
- else movex[thistran] += xx * ra + yy * rb,
- movey[thistran] += xx * rc + yy * rd;
- }
- break;
- case '/': /* Shrink */
- if (ptmode)
- { fx = 1 / (sizeinc + 1);
- warp(0.0, 0.0, fx, fx);
- }
- else
- { if ((sizex[thistran] /= sizeinc + 1) == 0)
- sizex[thistran] = ALMOSTZERO;
- if ((sizey[thistran] /= sizeinc + 1) == 0)
- sizey[thistran] = ALMOSTZERO;
- computef(thistran);
- }
- break;
- case '*': /* Grow */
- if (ptmode) warp(0.0, 0.0,sizeinc+1, sizeinc+1);
- else
- { if (((sizex[thistran] *= sizeinc + 1)
- > MAXSIZE)
- && (thistran > 0))
- sizex[thistran] = MAXSIZE;
- if (((sizey[thistran] *= sizeinc + 1)
- > MAXSIZE)
- && (thistran > 0))
- sizey[thistran] = MAXSIZE;
- computef(thistran);
- }
- break;
- case '[': /* Squish x-axis */
- if (ptmode) warp(0.0, 0.0, 1/(sizeinc + 1), 1.0);
- else
- { if ((sizex[thistran] /= (sizeinc + 1)) == 0)
- sizex[thistran] = ALMOSTZERO;
- computef(thistran);
- }
- break;
- case ']': /* Stretch x-axis */
- if (ptmode) warp(0.0, 0.0, sizeinc + 1, 1.0);
- else
- { if (((sizex[thistran] *= sizeinc + 1)
- > MAXSIZE)
- && (thistran > 0))
- sizex[thistran] = MAXSIZE;
- computef(thistran);
- }
- break;
- case '-': /* Spin counter-clockwise */
- if (ptmode) warp(-spininc, -spininc, 1.0, 1.0);
- else
- { if ((spinx[thistran] -= spininc) < 0)
- spinx[thistran] += TWOPI;
- if ((spiny[thistran] -= spininc) < 0)
- spiny[thistran] += TWOPI;
- computef(thistran);
- }
- break;
- case '+': /* Spin clockwise */
- if (ptmode) warp(spininc, spininc, 1.0, 1.0);
- else
- { if ((spinx[thistran] += spininc) >= TWOPI)
- spinx[thistran] -= TWOPI;
- if ((spiny[thistran] += spininc) >= TWOPI)
- spiny[thistran] -= TWOPI;
- computef(thistran);
- }
- break;
- case ';': /* Skew x-axis counter-clockwise */
- if (ptmode) warp(spininc, 0.0, 1.0, 1.0);
- else
- { if ((spinx[thistran] += spininc) >= TWOPI)
- spinx[thistran] -= TWOPI;
- computef(thistran);
- }
- break;
- case '\'': /* Skew x-axis clockwise */
- if (ptmode) warp(-spininc, 0.0, 1.0, 1.0);
- else
- { if ((spinx[thistran] -= spininc) < 0)
- spinx[thistran] += TWOPI;
- computef(thistran);
- }
- break;
- case '`': /* NextPoint */
- if (ptmode) ++thispt;
- else ptmode = ON, thistran = 0;
- if (thispt >= npts) thispt = 0;
- break;
- default:
- switch(a)
- { case TAB: /* Next part */
- if (ptmode)
- { ptmode = OFF;
- midpoint();
- }
- else
- { if (++thistran > ntrans) thistran = 0;
- }
- break;
- case 'D':
- case 'P':
- case 'B': /* Draw and/or Paint */
- _clearscreen(_GCLEARSCREEN);
- _setcliprgn(0, 0,
- vc.numxpixels - 1,
- vc.numypixels - 1);
- _setcolor(**color);
- if ((a == 'D') || (a == 'B'))
- draw(*fa, *fb, *fc, *fd,
- *movex, *movey, level);
- if ((a == 'P') || (a == 'B')) paint();
- printf("\7");
- getch();
- _clearscreen(_GCLEARSCREEN);
- printmenu();
- break;
- case ESC: /* Quit */
- _setvideomode(_DEFAULTMODE);
- printf("Seeyalater!");
- exit(0);
- case INSERT: /* Insert a point or part */
- if (ptmode)
- { if (npts < MAXPTS)
- { erase();
- ++npts;
- for (i = npts - 1; i > thispt; i--)
- x[i] = x[i - 1],
- y[i] = y[i - 1];
- if (thispt > 0)
- xx = x[thispt - 1],
- yy = y[thispt - 1];
- else xx = x[npts - 1],
- yy = y[npts - 1];
- if ((xx == x[thispt]) &&
- (yy == y[thispt]))
- x[thispt] += moveinc,
- y[thispt] += moveinc;
- else x[thispt] =
- (xx + x[thispt]) / 2,
- y[thispt] =
- (yy + y[thispt]) / 2;
- }
- else printf("\7");
- }
- else
- { if ((ntrans < MAXTRANS) && (ntrans > 0))
- { ++ntrans;
- for (i = ntrans; i > thistran; i--)
- { if (i > 1)
- { movex[i] = movex[i - 1];
- movey[i] = movey[i - 1];
- spinx[i] = spinx[i - 1];
- spiny[i] = spiny[i - 1];
- sizex[i] = sizex[i - 1];
- sizey[i] = sizey[i - 1];
- for (j = 0; j < NLEVELS;
- j++)
- color[i - 1][j] =
- color[i - 2][j];
- fa[i] = fa[i - 1];
- fb[i] = fb[i - 1];
- fc[i] = fc[i - 1];
- fd[i] = fd[i - 1];
- }
- else
- { spinx[1] = 0;
- spiny[1] = 0;
- sizex[1] = sizey[1];
- computef(1);
- }
- }
- if (thistran == 0) thistran = 1,i = 1;
- if (thistran > 1) j = thistran - 1;
- else j = ntrans;
- if ((movex[i] == movex[j]) &&
- (movey[i] == movey[j]))
- movex[i] += moveinc,
- movey[i] += moveinc;
- else movex[i] =
- (movex[i] + movex[j]) / 2,
- movey[i] =
- (movey[i] + movey[j]) / 2;
- }
- else
- { if (ntrans == 0) thistran = ++ntrans;
- else printf("\7");
- }
- }
- break;
- case DELETE: /* Delete a point or part */
- erase();
- if (ptmode)
- { if (npts > 1)
- { if (thispt == --npts) --thispt;
- else for (i = thispt; i < npts; i++)
- x[i] = x[i + 1],
- y[i] = y[i + 1];
- }
- else printf("\7");
- }
- else
- { if (ntrans > 0)
- { --ntrans;
- }
- else printf("\7");
- if (ntrans > 0)
- { if (thistran == 0) thistran = 1;
- else
- for (i = thistran;
- i <= ntrans; i++)
- { movex[i] = movex[i + 1];
- movey[i] = movey[i + 1];
- spinx[i] = spinx[i + 1];
- spiny[i] = spiny[i + 1];
- sizex[i] = sizex[i + 1];
- sizey[i] = sizey[i + 1];
- for (j = 0; j < NLEVELS;
- j++)
- color[i - 1][j] =
- color[i][j];
- fa[i] = fa[i + 1];
- fb[i] = fb[i + 1];
- fc[i] = fc[i + 1];
- fd[i] = fd[i + 1];
- }
- }
- if (thistran > ntrans) --thistran;
- }
- }
- sk = 1;
- }
- erase();
- sketch(sk);
- }
- }
- }
- /* midpoint() -- find the center of the seed */
- midpoint()
- { int xx, yy;
- midx = 0, midy = 0;
- for (i = 0; i < npts; i++) midx += x[i], midy += y[i];
- midx /= npts, midy /= npts;
- for (i = 0; i < npts; i++) x[i] -= midx, y[i] -= midy;
- for (i = 1; i <= ntrans; i++)
- { xx = midx * fa[i] + midy * fb[i];
- yy = midx * fc[i] + midy * fd[i];
- movex[i] -= midx - xx;
- movey[i] -= midy - yy;
- }
- xx = midx * *fa + midy * *fb,
- yy = midx * *fc + midy * *fd;
- *movex += xx,
- *movey += yy;
- }
-
- /* compute the affine transformations expressed by the template */
- computef(int i)
- { fa[i] = sizex[i] * cos(spinx[i]);
- fb[i] = -sizey[i] * sin(spiny[i]);
- fc[i] = sizex[i] * sin(spinx[i]);
- fd[i] = sizey[i] * cos(spiny[i]);
- if (i == 0)
- { if ((fx = *fa * *fd - *fb * *fc) == 0) fx = 0.001;
- ra = *fd / fx;
- rb = - *fb / fx;
- rc = - *fc / fx;
- rd = *fa / fx;
- }
- }
- /* warp the seed shape (used to skew, squish, and stretch) */
- void warp(float spinxinc, float spinyinc, float sizexinc, float sizeyinc)
- { float a, b, c, d, dsizex, dsizey, dspinx, dspiny;
- dspinx = spinxinc + *spinx;
- dspiny = spinyinc + *spiny;
- dsizex = sizexinc * *sizex;
- dsizey = sizeyinc * *sizey;
- a = cos(dspinx) * dsizex;
- b = -sin(dspiny) * dsizey;
- c = sin(dspinx) * dsizex;
- d = cos(dspiny) * dsizey;
- for (i = 0; i < MAXPTS; i++)
- { fx = x[i] * a + y[i] * b;
- fy = x[i] * c + y[i] * d;
- x[i] = fx * ra + fy * rb;
- y[i] = fx * rc + fy * rd;
- }
- }
-
- /* sketch() -- sketch the template and the handle.
- * Note that the handle shows not only which part you are on,
- * but also the relative size and orientation of both axes. */
- sketch(int all)
- { int i, j, x1, y1, inc, tran0 = 0;
- float x2, y2, a, b, c, d, mx, my;
- inc = hand;
- if (ptmode)
- { tran0 = 1;
- inc *= *sizey / 2;
- fx = x[thispt], fy = y[thispt];
- x1 = fx * *fa + fy * *fb + *movex;
- y1 = fx * *fc + fy * *fd + *movey;
- xctr = x1, yctr = (y1 + inc) * asprat;
- xtop = x1, ytop = (y1 - inc) * asprat;
- y1 *= asprat;
- xlft = x1 - inc, ylft = y1;
- xrgt = x1 + inc, yrgt = y1;
- }
- else
- { if (thistran == 0) x1 = 0, y1 = 0, tran0 = 1;
- else x1 = movex[thistran], y1 = movey[thistran];
- if (tran0) fx = x1, fy = y1 - inc;
- else fx = x1 - inc * fb[thistran],
- fy = y1 - inc * fd[thistran];
- xtop = fx * *fa + fy * *fb + *movex;
- ytop = (fx * *fc + fy * *fd + *movey) * asprat;
- xctr = x1 * *fa + y1 * *fb + *movex;
- yctr = (x1 * *fc + y1 * *fd + *movey) * asprat;
- inc /= 2;
- if (tran0) fx = x1 - inc, fy = y1;
- else fx = x1 - inc * fa[thistran],
- fy = y1 - inc * fc[thistran];
- xlft = fx * *fa + fy * *fb + *movex;
- ylft = (fx * *fc + fy * *fd + *movey) * asprat;
- if (tran0) fx = x1 + inc, fy = y1;
- else fx = x1 + inc * fa[thistran],
- fy = y1 + inc * fc[thistran];
- xrgt = fx * *fa + fy * *fb + *movex;
- yrgt = (fx * *fc + fy * *fd + *movey) * asprat;
- }
- _setcolor(**color);
- for (j = 0; j < npts; j++)
- { x1 = x[j] * *fa + y[j] * *fb + *movex;
- y1 = (x[j] * *fc + y[j] * *fd + *movey) * asprat;
- (*xo)[j] = x1, (*yo)[j] = y1;
- if (j == 0) _moveto(x1, y1);
- else _lineto(x1, y1);
- }
- _lineto(**xo, **yo);
- for (i = 1; i <= ntrans; i++)
- { if ((thistran == 0) || (i == thistran) || (all))
- { _setcolor(color[i - 1][level]);
- a = fa[i] * *fa + fc[i] * *fb;
- b = fb[i] * *fa + fd[i] * *fb;
- c = fa[i] * *fc + fc[i] * *fd;
- d = fb[i] * *fc + fd[i] * *fd;
- mx = movex[i] * *fa + movey[i] * *fb + *movex;
- my = movex[i] * *fc + movey[i] * *fd + *movey;
- for (j = 0; j < npts; j++)
- { x1 = a * x[j] + b * y[j] + mx;
- y1 = (c * x[j] + d * y[j] + my) * asprat;
- if (j == 0) _moveto(x1, y1);
- else _lineto(x1, y1);
- xo[i][j] = x1, yo[i][j] = y1;
- }
- _lineto(*(xo[i]), *(yo[i]));
- }
- }
- _setcolor(drawclr);
- _moveto(xtop, ytop);
- _lineto(xctr, yctr);
- _moveto(xlft, ylft);
- _lineto(xrgt, yrgt);
- }
- /* erase the template */
- erase()
- { _setcolor(0);
- _moveto(**xo, **yo);
- for (i = 1; i < npts; i++) _lineto((*xo)[i], (*yo)[i]);
- _lineto(**xo, **yo);
- for (i = 1; i <= ntrans; i++)
- { if ((thistran == 0) || (i == thistran))
- { _moveto(*(xo[i]), *(yo[i]));
- for (j = 0; j < npts; j++) _lineto(xo[i][j], yo[i][j]);
- _lineto(*(xo[i]), *(yo[i]));
- }
- }
- _moveto(xtop, ytop);
- _lineto(xctr, yctr);
- _moveto(xlft, ylft);
- _lineto(xrgt, yrgt);
- }
-
- /* paint() -- uses the "Chaos Game", or "random iteration" algorithm
- * to paint the "infinite-level" fractal on the screen. */
- paint()
- { int i, j, p[MAXTRANS], tc, tp, ci[NLEVELS], cc = 0, mx, my;
- unsigned long ct = COUNT;
- float x1 = 0.0, y1 = 0.0, x2, y2 = 0, sx[MAXTRANS], sy[MAXTRANS];
- mx = *movex, my = *movey;
-
- /* First, we need to compute the relative area of each part of the
- template. This is done by comparing the size of the determinants
- of the matrix (a,b,c,d). These weights are then used to decide
- how often to visit each part--big parts get more visits than small
- ones, giving the overall fractal an even density. */
- for (i = 1; i <= ntrans; i++)
- y2 += (sx[i - 1] =
- fabs(fa[i] * fd[i] - fb[i] * fc[i]));
- if (y2 == 0) y2 = 0.01;
- x2 = MAXINT / y2;
- j = 0;
- for (i = 0; i < ntrans; i++)
- { if ((xx = sx[i] * x2) == 0) xx = 1;
- p[i] = (j += xx);
- }
-
- /* We skip the first eight points on our journey, because it may take
- that long to settle down from wherever we started onto the fractal.*/
- for (j = 0; j < 8; j++)
- { i = rand() % ntrans + 1;
- x2 = x1 * fa[i] + y1 * fb[i] + movex[i];
- y2 = x1 * fc[i] + y1 * fd[i] + movey[i];
- x1 = x2, y1 = y2;
- ci[cc] = i;
- if (++cc == level) cc = 0;
- }
-
- /* Now we put it on the screen. The cc, tc, and ci variables are used
- to determine coloring. At each iteration, we choose a level at
- random out of all the levels we will be coloring. We then find the
- color for that level based on which part was "visited" that many
- iterations ago. How does this work? Each iteration of the orbit
- goes from a point on the "whole" to a point on a "part". Therefore,
- if we were in part #3 one iteration ago, we are now in a level 1
- reflection of part #3 within the current part. If we were at part #5
- two cycles ago, we are now painting a point within a level 2
- reflection of part #5, and so on. */
- while(!kbhit() && (--ct != 0))
- { j = rand();
- for (i = 0; i < ntrans; i++) if (j < p[i]) break;
- i++;
- x2 = x1 * fa[i] + y1 * fb[i] + movex[i];
- y2 = x1 * fc[i] + y1 * fd[i] + movey[i];
- x1 = x2, y1 = y2;
- ci[cc] = i - 1;
- j = rand() % level;
- if ((i = cc - j) < 0) i += level;
- if ((tc = color[ci[i]][j + 1]) > 0)
- { _setcolor(tc);
- _setpixel((int) (x2 * *fa + y2 * *fb + mx),
- (int) ((x2 * *fc + y2 * *fd + my) * asprat));
- }
- if (++cc == level) cc = 0;
- }
- }
-
- /* draw() -- uses the "successive approximation" algorithm to draw
- the fractal.*/
- void draw(float a, float b, float c, float d, float mx, float my, int iter)
- { int i;
-
- /* When we start drawing, iter is the number of levels to draw.
- Each time we go down one level, we decrement iter. */
- iter--;
-
- /* If user hits ESC, pass that keypress up through the recursive
- calls until we get back to the main procedure.*/
- if (kbhit() && (getch() == ESC))
- { ungetch(ESC);
- return;
- }
-
- /* Draw a reflection of the seed polygon using the current
- transformation */
- for (i = 0; i < npts; i++)
- { fx = x[i] * a + y[i] * b + mx;
- fy = x[i] * c + y[i] * d + my;
- if (i == 0)
- { xx = fx, yy = fy;
- _moveto((int) fx, (int) (fy * asprat));
- }
- else _lineto((int) fx, (int) (fy * asprat));
- }
- _lineto((int) xx, (int) (yy * asprat));
-
- /* If iter has counted all the way down to zero, don't draw the next
- deepest level, but back out one level instead */
-
- if (iter < 0) return;
- else
- { /* Call draw recursively for each transformation, drawing the
- next deepest level of each part */
- for (i = 1; i <= ntrans; i++)
- { _setcolor(color[i - 1][level - iter]);
- draw(fa[i] * a + fc[i] * b,
- fb[i] * a + fd[i] * b,
- fa[i] * c + fc[i] * d,
- fb[i] * c + fd[i] * d,
- a * movex[i] + b * movey[i] + mx,
- c * movex[i] + d * movey[i] + my,
- iter);
- }
- }
- }
-
- /* display the menu */
- printmenu()
- { _settextwindow(1, vc.numtextcols - MENUWD,
- vc.numtextrows, vc.numtextcols);
- _clearscreen(_GWINDOW);
- _outtext(MENUMSG);
- _settextposition(menuitem + 2, 1);
- _outtext(">");
- _setcliprgn(0, 0, vc.numxpixels - (MENUWD + 1) *
- (vc.numxpixels / vc.numtextcols) - 1,
- vc.numypixels - 1);
- }
-
- /* hello() -- initialize everything */
- hello()
- { if (!_setvideomode(_VRES16COLOR))
- { printf("Can't set video mode. VGA required.");
- }
- _getvideoconfig(&vc);
- _remapallpalette(palette);
- _wrapon(_GWRAPOFF);
- _clearscreen(_GCLEARSCREEN);
- printmenu();
- asprat = (float) (4 * vc.numypixels) / (float) (3 * vc.numxpixels);
- drawclr = vc.numcolors - 1;
- for (i = 0; i <= ntrans; i++) computef(i);
- sketch(0);
- }
-
- [LISTING FIVE]
-
- /*****************************************************************
- FLAKE.H --- Header file for snowflake template
- This (and the other header files like it) can be used to define
- the initial fractal template for the SIERP.C and FRACDRAW.C programs
- This template models the crystalization process to draw a realistic
- snowflake shape.
- See additional comments in SIERP.H
- *****************************************************************/
- #define NPOINTS 6 /* Number of points on the "parent" polygon */
- #define NTRANS 6 /* Number of transformed "children" */
- #define NLEVELS 5 /* Number of levels to draw */
- #define COUNT 10000 /* Number of dots to paint */
- #define CENTERX 320 /* Center of the screen */
- #define CENTERY 240
- #define SEEDX 1,21,21,1,-21,-21 /* The "parent" polygon */
- #define SEEDY -27,-15,9,40,9,-15
-
- /* The tranformations which define the "children" */
- #define MOVEX -1,55,55,1,-55,-55 /* Displacement */
- #define MOVEY -65,-35,35,65,35,-35
- #define SIZEX .18,.18,.18,.18,.18,.18 /* Size change */
- #define SIZEY .91,.91,.91,.91,.91,.91
- #define SPINX 0,1.05,2.09,3.14,4.19,5.24 /* Rotation */
- #define SPINY 0,1.05,2.09,3.14,4.19,5.24
-
- #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
- _BLUE, _MAGENTA, _BROWN, _WHITE, \
- _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
- _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
-
- #define COLOR {{15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15}}
-
- [LISTING SIX]
-
- /****************************************************************
- CUMULUS.H--- Header file for cumulus cloud template
- This (and the other header files like it) can be used to define
- the initial fractal template for the SIERP.C and FRACDRAW.C programs
- See additional comments in SIERP.H
- ****************************************************************/
-
- #define NPOINTS 7 /* Number of points on the "parent" polygon */
- #define NTRANS 6 /* Number of transformed "children" */
- #define NLEVELS 5 /* Number of levels to draw */
- #define COUNT 10000 /* Number of dots to paint */
- #define CENTERX 320 /* Center of the screen */
- #define CENTERY 240
- #define SEEDX 23,17,-4,-10,-27,7,44 /* The "parent" polygon */
- #define SEEDY 0,55,55,0,9,-66,10
-
- /* The tranformations which define the "children" */
- #define MOVEX 85,-94,-3,51.5,-49,0 /* Displacement */
- #define MOVEY 15,13,3.5,-35,-40,40
- #define SIZEX .36,.4,.53,.48,.4,.87 /* Size change */
- #define SIZEY .36,.47,.53,.53,.4,.33
- #define SPINX .25,6,6.2,0.15,6.2,0 /* Rotation */
- #define SPINY .25,6,6.2,0.15,6.2,6.3
-
- #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
- _BLUE, _MAGENTA, _BROWN, _WHITE, \
- _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
- _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
-
- #define COLOR {{15,15,15, 7, 8},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15}}
-
- /*****************************************************************
- CIRRUS.H-- Header file for cirrus cloud template
- In this and the other cloud models (STRATUS and CUMULUS), the air
- currents which control cloud formation are modelled as arrows.
- When those forces are reflected throughout all levels of scale,
- a realistic image of the cloud type that results from those air
- currents appears. Cirrus clouds are characterized by high-altitude
- rising cross winds, stratus clouds by slow horizontal air flow,
- and cumulus clouds by warm air rising from the ground.
- *****************************************************************/
-
- #define NPOINTS 7 /* Number of points on the "parent" polygon */
- #define NTRANS 6 /* Number of transformed "children" */
- #define NLEVELS 5 /* Number of levels to draw */
- #define COUNT 10000 /* Number of dots to paint */
- #define CENTERX 180 /* Center of the screen */
- #define CENTERY 240
- #define SEEDX 16,-27,-42,-7,-27,54,23 /* The "parent" polygon */
- #define SEEDY 33,52,36,-7,-13,-43,36
-
- /* The tranformations which define the "children" */
- #define MOVEX 143.4,-90,5,-4 /* Displacement */
- #define MOVEY 11.08,13.6,-15.5,45
- #define SIZEX .75,.43,.38,.75 /* Size change */
- #define SIZEY .45,.47,.44,.21
- #define SPINX 6.07,0.05,0.02,0.0 /* Rotation */
- #define SPINY 6.07,0.05,0.02,6.28
-
- #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
- _BLUE, _MAGENTA, _BROWN, _WHITE, \
- _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
- _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
-
- #define COLOR {{15,15,15, 7, 8},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15}}
-
-
- /*****************************************************************
- LEAF.H --- Header file for maple leaf template
- This is the "geometric genetic code" for a maple leaf. Note the close
- similarity to the MAPLE tree template.
- *****************************************************************/
- #define NPOINTS 4 /* Number of points on the "parent" polygon */
- #define NTRANS 4 /* Number of transformed "children" */
- #define NLEVELS 6 /* Number of levels to draw */
- #define COUNT 10000 /* Number of dots to paint */
- #define CENTERX 320 /* Center of the screen */
- #define CENTERY 350
- #define SEEDX 6,20,-6,-12 /* The "parent" polygon */
- #define SEEDY -120,120,120,-120
-
- /* The tranformations which define the "children" */
- #define MOVEX -1.15,-53,51,-6 /* Displacement */
- #define MOVEY 35,7,6,-111
- #define SIZEX 0.14,0.62,0.65,0.49 /* Size change */
- #define SIZEY 0.51,0.72,0.68,0.51
- #define SPINX 6.26,5.47,0.81,6.28 /* Rotation */
- #define SPINY 6.26,5.47,0.81,6.28
-
- #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
- _BLUE, _MAGENTA, _BROWN, _WHITE, \
- _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
- _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
-
- #define COLOR {{6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2},\
- {6, 6,14,14,10, 2}}
-
- /*****************************************************************
- MOUSE.H -- Header file for cartoon mouse template
- This template was made by tracing the rough outline of an image and
- tiling with copies of itself.
- *****************************************************************/
- #define NPOINTS 14 /* Number of points on the "parent" polygon */
- #define NTRANS 18 /* Number of transformed "children" */
- #define NLEVELS 2 /* Number of levels to draw */
- #define COUNT 50000 /* Number of dots to paint */
- #define CENTERX 320 /* Center of the screen */
- #define CENTERY 240
- #define SEEDX 131,140,97,6,-56,-97,-146,-148,-121,-101,-47,-3,32,29
- #define SEEDY 5,55,99,133,121,70,21,-17,-17,-31,-20,-78,-93,-71
-
- /* The tranformations which define the "children" */
- #define MOVEX -89,36,-60,-4,4,61,-71,1,81,-49,-133,-130,-8,-3,-36,-24,13,15
- #define MOVEY -3,13,25,-35,-63,-43,101,116,56,87,-50,-24,104,-1,-20,-27,-16,76
- #define SIZEX .31,.4,.62,.07,.19,.32,.19,.4,.55,.31,.12,.17,.21,.06,.06,\
- .08,.11,.42
- #define SIZEY .18,.35,.44,.27,.27,.48,.06,.13,.33,.20,.04,.23,.12,.16,.14,\
- .2,.23,.2
- #define SPINX 3.23,6.4,.32,2.72,5.84,4.61,.75,6.25,5.34,.29,3.16,5.9,3.04,\
- 4.15,4.32,.91,1.1,2.55
- #define SPINY 3.6,6.5,.77,.37,3.49,4.28,.75,6.25,5.27,.1,2.85,2.65,2.53,\
- 3.56,3.73,3.73,3.53,5.89
-
- #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
- _BLUE, _MAGENTA, _BROWN, _WHITE, \
- _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
- _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
-
- #define COLOR {{6,6},\
- {6,6},\
- {6,6},\
- {6,6},\
- {6,6},\
- {6,6},\
- {1,1},\
- {6,6}, {6,6}, {1,1}, {7,7}, {8,8}, {12,12},\
- {9,9}, {9,9}, {15,15}, {15,15}, {1,1}}
-
- /*****************************************************************
- PINE.H --- Header file for pine tree template
- This (and the other header files like it) can be used to define
- the initial fractal template for the SIERP.C and FRACDRAW.C programs
- *****************************************************************/
-
- #define NPOINTS 4 /* Number of points on the "parent" polygon */
- #define NTRANS 6 /* Number of transformed "children" */
- #define NLEVELS 5 /* Number of levels to draw */
- #define COUNT 10000 /* Number of dots to paint */
- #define CENTERX 320 /* Center of the screen */
- #define CENTERY 350
- #define SEEDX 6,20,-6,-12 /* The "parent" polygon */
- #define SEEDY -120,120,120,-120
-
- /* The tranformations which define the "children" */
-
- #define MOVEX -41.2,36.9,5.13,-14.64,2.2,40.07 /* Displacement */
- #define MOVEY 14.987,-61.31,7.10,-32.33,-50.46
- #define SIZEX 0.39,0.41,0.52,0.35,0.86,0.37 /* Size change */
- #define SIZEY 0.39,0.31,0.17,0.24,0.79,0.42
- #define SPINX 5.62,0.61,6.15,5.43,3.27,0.54 /* Rotation */
- #define SPINY 4.91,1.27,0.13,4.71,6.28,1.4
-
- #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
- _BLUE, _MAGENTA, _BROWN, _WHITE, \
- _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
- _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
-
- #define COLOR {{6, 6,14,10, 2},\
- {6, 6,14,10, 2},\
- {6, 6,14,10, 2},\
- {6, 6,14,10, 2},\
- {6, 6,14,10, 2},\
- {6, 6,14,10, 2},\
- {6, 6,14,10, 2},\
- {6, 6,14,10, 2},\
- {6, 6,14,10, 2}}
- /*****************************************************************
- STRATUS.H -- Header file for stratus cloud template
- ****************************************************************/
-
- #define NPOINTS 6 /* Number of points on the "parent" polygon */
- #define NTRANS 5 /* Number of transformed "children" */
- #define NLEVELS 5 /* Number of levels to draw */
- #define COUNT 10000 /* Number of dots to paint */
- #define CENTERX 320 /* Center of the screen */
- #define CENTERY 240
- #define SEEDX 40,80,40,-40,-80,-40 /* The "parent" polygon */
- #define SEEDY 22,-2,-22,-22,2,22
-
- /* The tranformations which define the "children" */
- #define MOVEX -70,-44,45,60,-3.3 /* Displacement */
- #define MOVEY 11,-34,-31,1.6,42
- #define SIZEX .75,.43,.38,.75,.8 /* Size change */
- #define SIZEY .45,.47,.44,.61,.2
- #define SPINX 6.3,6.3,6.3,6.3,0 /* Rotation */
- #define SPINY 6.3,6.3,6.3,6.3,6.3
-
- #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
- _BLUE, _MAGENTA, _BROWN, _WHITE, \
- _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
- _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
-
- #define COLOR {{15,15,15, 7, 8},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15},\
- {15,15,15,15,15}}
- /*****************************************************************
- ZOOM.H -- Header file for abstract zooming artwork template
- Note that this very simple template creates a visually complex image,
- while seemingly simple linear forms like the cartoon mouse require
- much more work and information to express as fractals. When drawing
- with fractals, richly detailed trees are simpler and easier to create
- than smooth objects like tables and chairs!
- *****************************************************************/
-
- #define NPOINTS 5 /* Number of points on the "parent" polygon */
- #define NTRANS 5 /* Number of transformed "children" */
- #define NLEVELS 4 /* Number of levels to draw */
- #define COUNT 20000 /* Number of dots to paint */
- #define CENTERX 320 /* Center of the screen */
- #define CENTERY 340
- #define SEEDX -66,-334,60,272,66
- #define SEEDY -7,100,-120,-27,55
-
- /* The tranformations which define the "children" */
-
- #define MOVEX 55,104,185,30,-45
- #define MOVEY -309,-1,-50,28,-25
- #define SIZEX .27,.36,.5,.28,.98
- #define SIZEY .27,.27,.18,.21,.5
- #define SPINX 4.71,3.88,3.34,4.3,6
- #define SPINY 2.48,.93,.39,1.16,6
-
- #define PALETTE {_BLUE, _RED, _GREEN, _CYAN, \
- _BLACK, _MAGENTA, _BROWN, _WHITE, \
- _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
- _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
-
- #define COLOR {{15,15,15,15},\
- {14,14,14,14},\
- {14,14,14,14},\
- {14,14,14,14},\
- {14,14,14,14},\
- {15,15,15,15},\
- {15,15,15,15}}
-